#!/usr/bin/env python3
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

import getopt
import os
import sys
import time
from pathlib import Path

import livestatus


def usage():
    sys.stdout.write(
        """usage: check_notify_count OPTIONS

OPTIONS:
  -h, --help    Show this help message and exit
  -l PATH       Path to livestatus socket (Autodetected in OMD)
  -r MINUTES    Timerange in the past to observe, given in minutes.
                Default is set to 60 minutes.
  -w NUM        Minumum number of notifications per contact in
                timerange to raise a WARNING state.
                Disabled by default.
  -c NUM        Minumum number of notifications per contact in
                timerange to raise a CRITICAL state.
                Disabled by default.

"""
    )


short_options = "hr:w:c:l:"

try:
    opts, args = getopt.getopt(sys.argv[1:], short_options)
except getopt.GetoptError as err:
    sys.stderr.write("%s\n" % err)
    sys.exit(1)

socket_path = None
timerange = 60
warn, crit = None, None

for o, a in opts:
    if o == "-h":
        usage()
        sys.exit(0)
    elif o == "-r":
        timerange = int(a)
    elif o == "-w":
        warn = int(a)
    elif o == "-c":
        crit = int(a)
    elif o == "-l":
        socket_path = Path(a)

if len(args) == 1:
    sys.stderr.write("ERROR: No service pattern given.\n")
    sys.exit(1)

if socket_path is None and "OMD_ROOT" in os.environ:
    socket_path = Path(os.environ["OMD_ROOT"]) / "tmp/run/live"

# The condition when socket_path is empty and OMD_ROOT is not set, so I consider it an error
if socket_path is None or not socket_path.exists():
    sys.stderr.write("ERROR: Livestatus socket (%s) does not exist\n" % socket_path)
    sys.exit(1)

query = (
    "GET log\n"
    "Columns: log_contact_name\n"
    "Filter: log_time >= %d\n"
    "Filter: class = 3\n"
    "Stats: state != 999\n"
) % (int(time.time() - (timerange * 60)))

c = livestatus.SingleSiteConnection(f"unix:{socket_path}")

total_num = 0
perfdata = []
state = 0
details = []

num_users = 0
raw_notifications = 0
for contact_name, num in c.query_table(query):
    # This results in an invalid metric and should therefore be skipped.
    if contact_name == "":
        continue
    if contact_name == "check-mk-notify":
        raw_notifications += num
    else:
        total_num += num

        if crit is not None and num > crit:
            state = max(state, 2)
            details.append("%s got %d (> %d)(!!)" % (contact_name, num, crit))

        elif warn is not None and num > warn:
            state = max(state, 1)
            details.append("%s got %d (> %d)(!)" % (contact_name, num, warn))

    perfdata.append("%s_num=%d" % (contact_name, num))

detail_txt = " (%s)" % ", ".join(details) if details else ""
sys.stdout.write(
    "%d raw notifications, %d user notifications within last %d minutes%s | %s\n"
    % (raw_notifications, total_num, timerange, detail_txt, " ".join(perfdata))
)
